﻿using Clancy.Data;
using Clancy.Interfaces;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;

namespace Clancy.Bl
{
    public class OnlineOperationAdapter : IOnlineOperationAdapter
    {
        private readonly ObservableCollection<IRecording> m_RecordingCollection = new ObservableCollection<IRecording>();
        private readonly IServerConnectionLogic m_ServerConnectionLogic;

        private readonly ObservableCollection<ISurveilanceObject> m_SurveilanceObjects = new ObservableCollection<ISurveilanceObject>();

        private readonly Dictionary<Guid, IOnlineSurveilanceStatus> m_SurveilanceStatusAdapters = new Dictionary<Guid, IOnlineSurveilanceStatus>();
        private ISurveilanceStorage m_Storage;

        public OnlineOperationAdapter(IServerConnectionLogic serverConnectionLogic, ISurveilanceStorage storage)
        {
            m_Storage = storage;
            m_ServerConnectionLogic = serverConnectionLogic;
        }

        public ObservableCollection<IRecording> RecordingCollection
        {
            get { return m_RecordingCollection; }
        }

        public Task AddNewSource(IVideoSourceFilterInfo videoSourceFilterInfo)
        {
            m_ServerConnectionLogic.AddNewSource(videoSourceFilterInfo);
            return Task.FromResult(true);
        }

        public Task<bool> DeleteRecording(Guid selectedRecordingId)
        {
            return m_ServerConnectionLogic.DeleteRecording(selectedRecordingId);
        }

        public Task DeleteVideoSource(ISurveilanceObject selectedSurveilanceObject)
        {
            m_ServerConnectionLogic.RemoveSource(selectedSurveilanceObject);
            return Task.FromResult(true);
        }

        public void Dispose()
        {
            m_ServerConnectionLogic.Disconnect();
        }

        public ISurveilanceObject[] GetAllSurveilances()
        {
            return m_ServerConnectionLogic.GetAllSurveilances();
        }

        public IVideoSourceFilterInfo[] GetAvailableSources()
        {
            return m_ServerConnectionLogic.GetAvailableSources().ToArray();
        }

        public ISurveilanceStatus GetSurveilance(ISurveilanceObject surveilanceObject)
        {
            return GetSurveilanceStatusAdapter(surveilanceObject);
        }

        public void SetResultFrame(ISurveilanceObject surveilanceObject, ISurveilanceResultFrame frame)
        {
            if (!m_SurveilanceStatusAdapters.ContainsKey(surveilanceObject.Id))
                return;

            m_SurveilanceStatusAdapters[surveilanceObject.Id].SetCurrentProcessedFrame(frame);
        }

        public Task ShowAdvancedVideoDialog(ISurveilanceObject selectedSurveilanceObject)
        {
            throw new NotImplementedException();
        }

        public Task StartVideoStream(ISurveilanceObject survObj)
        {
            return m_ServerConnectionLogic.StartVideostream(survObj);
        }

        public Task StopVideoStream(ISurveilanceObject survObj)
        {
            return m_ServerConnectionLogic.StopVideostream(survObj);
        }

        public Task UpdateSurveilanceObject(ISurveilanceObject surveilanceObject)
        {
            return m_ServerConnectionLogic.UpdateSurveilanceObject(surveilanceObject);
        }

        public Task UpdateSurveilanceObject(ISurveilanceObject surveilanceObject, string propertyName)
        {
            object value = surveilanceObject.GetType().GetProperty(propertyName).GetValue(surveilanceObject, null);
            m_ServerConnectionLogic.UpdateSurveilanceObject(surveilanceObject.Id, propertyName, value);
            return Task.FromResult(true);
        }

        private ISurveilanceStatus GetSurveilanceStatusAdapter(ISurveilanceObject surveilanceObject)
        {
            if (!m_SurveilanceStatusAdapters.ContainsKey(surveilanceObject.Id))
                m_SurveilanceStatusAdapters[surveilanceObject.Id] = new OnlineSurveilanceStatus(surveilanceObject);

            return m_SurveilanceStatusAdapters[surveilanceObject.Id];
        }
    }
}